using System.Collections.Generic;
using System.Xml;
using System.IO;
using com.tc.assistance.protocol.entity;
using com.tc.assistance.entity.device;
namespace com.tc.assistance.parser{


public class ProtocolParser {
	static Dictionary<string, bool> fields = new  Dictionary<string, bool>();
    static ProtocolParser(){
		fields.Add("action", true);
        fields.Add("fromComponent", true);
        fields.Add("toComponent", true);
        fields.Add("from", true);
        fields.Add("to", true);
}


	
	static public ProtocolMessage parseProtocolMessage(string xml){
		
		XmlDocument doc = new XmlDocument ( ) ;
        doc.LoadXml(xml);
		XmlElement re = doc.DocumentElement;
		
				ProtocolMessage r;
				if(re.Name.Equals("request"))
					r = new Request();
				else if(re.Name.Equals("report"))
					r = new Report();
				else return null;
				XmlAttributeCollection map = re.Attributes;
				for(int i = 0; i < map.Count; i++){
					string name = map.Item(i).Name;

					string value = map.Item(i).Value;
					if(fields.ContainsKey(name)){
						r.GetType().GetField(name).SetValue(r,value);
					}else{
						r.attributes.Add(name, value);
					}
				}
				return r;

	}
	static public ProtocolMessage parseProtocolMessage(Dictionary<string, string> ps){
		
				string command = ps["ciommand"];
        if(command != null)
            ps.Remove("ciommand");
        else
            return null;

				ProtocolMessage r;
				if(command.Equals("request"))
					r = new Request();
				else if(command.Equals("report"))
					r = new Report();
				else return null;
				
				foreach(string name in ps.Keys){
					string value = ps[name];
				
					if(fields.ContainsKey(name)){

							r.GetType().GetField(name).SetValue(r, value);
	
					}else{
						r.attributes.Add(name, value);
					}
				}
			
			return null;
	}
	static public GeneralDevice parseDeviceDefination(Stream stream){
        XmlReader reader = XmlReader.Create(stream);
        XmlDocument doc = new XmlDocument();
        doc.Load(reader);
		
				return parseDeviceDefination(doc.DocumentElement);

	}
	static public GeneralDevice parseDeviceDefination(XmlElement nd){
		GeneralDevice ca = new GeneralDevice();

		string mid = nd.GetAttribute("id");
		ca.setId(mid);
		ca.setName(nd.GetAttribute("name"));
		ca.setFixedType(bool.Parse(nd.GetAttribute("fixedType")));
		ca.setOwnerId(nd.GetAttribute("ownerId"));
		ca.setType(nd.GetAttribute("type"));

		string sc = nd.GetAttribute("supportedChannel");
		sc = sc.Substring(1, sc.Length - 2);
		string[] ss = sc.Split(new char[]{','});
		if(ss.Length> 0){
			List<string> s = new List<string>();
			foreach(string se in ss)
				s.Add(se);
			ca.setSupportedChannel(s);
		}
		XmlNodeList dcs = nd.GetElementsByTagName("deviceComponents");
		if(dcs != null && dcs.Count != 0){
            XmlElement dd = (XmlElement)dcs.Item(0);
			
			Dictionary<string, DeviceComponent> coms = components(dd);
			ca.setComponents(coms);
		}
		return ca;
	}

    static Dictionary<string, DeviceComponent> components(XmlElement node)
    {
        Dictionary<string, DeviceComponent> coms = new Dictionary<string, DeviceComponent>();
		XmlNodeList nl = node.GetElementsByTagName("deviceComponent");
		for (int j = 0; j < nl.Count; j++) {
			XmlElement com = (XmlElement)nl.Item(j);
		
				DeviceComponent dc = new DeviceComponent();
				dc.setComponentType(com.GetAttribute("componentType"));
				dc.setLocalId(com.GetAttribute("localId"));
				dc.setName(com.GetAttribute("name"));
				coms.Add(dc.getLocalId(), dc);

		}
		return coms;
	}
    static public Dictionary<string, string> parseDeviceParams(Stream stream)
    {
        Dictionary<string, string> rst = new Dictionary<string, string>();
        XmlReader reader = XmlReader.Create(stream);
        XmlDocument doc = new XmlDocument();
        doc.Load(reader);
		
		XmlElement root = doc.DocumentElement;

				XmlNodeList vs = root.GetElementsByTagName("statusItem");
				for(int i = 0; i < vs.Count; i++){
					XmlElement v = (XmlElement)vs.Item(i);
					rst.Add(v.GetAttribute("localId"),v.GetAttribute("status"));
				}

			
		
		return rst;
	}
public static DetailedRelation parseDeviceRelation(Stream stream) {
    Dictionary<string, string> rst = new Dictionary<string, string>();
    XmlReader reader = XmlReader.Create(stream);
    XmlDocument doc = new XmlDocument();
    doc.Load(reader);

    XmlElement root = doc.DocumentElement;
		return  parseDeviceRelation(root);

	}
	public static DetailedRelation parseDeviceRelation(XmlElement relationNode) {
	
		
		XmlElement ind = (XmlElement)relationNode.GetElementsByTagName("in").Item(0);
		XmlElement outd = (XmlElement)relationNode.GetElementsByTagName("out").Item(0);
		
		return new DetailedRelation(relations(ind), relations(outd));
	}
	static List<Relationship> relations(XmlElement root){
		List<Relationship> rst = new List<Relationship>();
		XmlNodeList nrs = root.GetElementsByTagName("relationship");
		for(int i = 0; i < nrs.Count; i++)
		{
			XmlElement er = (XmlElement)nrs.Item(i);
			Relationship r = new Relationship();
			r.setFromId(er.GetAttribute("fromId"));
			r.setToId(er.GetAttribute("toId"));
			r.setName(er.GetAttribute("name"));
			r.setReverseName(er.GetAttribute("reverseName"));
			rst.Add(r);
		}
		return rst;
	}
	public static DeviceRelation  parseSimpleRelation(Stream stream) {
		 Dictionary<string, string> rst = new Dictionary<string, string>();
    XmlReader reader = XmlReader.Create(stream);
    XmlDocument doc = new XmlDocument();
    doc.Load(reader);

    XmlElement root = doc.DocumentElement;
			string ins = root.GetAttribute("in");
			ins = ins.Substring(1, ins.Length - 1);
			string[] ss = ins.Split(new char[]{','});
			List<string> ind = new List<string>();
			if(ss.Length > 0){
				
				foreach(string se in ss)
					ind.Add(se);
			}
			
			string outs = root.GetAttribute("out");
			outs = outs.Substring(1, ins.Length - 1);
			ss = outs.Split(new char[]{','});
			List<string> outd = new List<string>();
			if(ss.Length > 0){
				
				foreach(string se in ss)
					outd.Add(se);
			}
			DeviceRelation r = new DeviceRelation(ind, outd);
			return  r;

	
}
}
}